package thss.mse12.lau.rsa.c;

import java.util.Random;

public class BigInteger {
	/*
	 * big-endian. no sign bit.
	 */
	public boolean[] value;

	/*
	 * the length of value;
	 */
	public int length;

	/*
	 * if value >=0, sign =true; else sign = false
	 */
	public boolean sign;

	/*
	 * 
	 * generate a random biginteger which has length bits.
	 */
	public BigInteger(int length, Random rnd) {
		this.sign = true;
		this.length = length;
		this.value = new boolean[length];
		for (int i = 0; i < length; i++) {
			this.value[i] = rnd.nextBoolean();
		}
		this.value[0] = true;
	}

	public BigInteger(int length) {
		this.length = length;
		this.sign = true;
		this.value = new boolean[length];
	}

	/*
	 * only for two positive number.
	 */
	public BigInteger add(BigInteger op) {
		int len = 0;
		if (this.length > op.length) {
			len = this.length;
		} else if (this.length < op.length) {
			len = op.length;
		} else {
			len = this.length + 1;
		}
		BigInteger rlt = new BigInteger(len);
		boolean carry = false;
		int j = -1;
		for (int i = len - 1; i >= 0; i--) {
			j = len - i;
			if (this.length - j < 0 && op.length - j >= 0) {
				if (carry) {
					if (op.value[op.length - j]) {
						rlt.value[i] = false;
					} else {
						rlt.value[i] = true;
						carry = false;
					}
				} else {
					rlt.value[i] = op.value[op.length - j];
				}
			} else if (this.length - j >= 0 && op.length - j < 0) {
				if (carry) {
					if (this.value[length - j]) {
						rlt.value[i] = false;
					} else {
						rlt.value[i] = true;
						carry = false;
					}
				} else {
					rlt.value[i] = this.value[length - j];
				}
			} else if (this.length - j < 0 && op.length - j < 0) {
				rlt.value[i] = carry;
			} else if (this.value[this.length - j] && op.value[op.length - j]) {
				if (carry) {
					rlt.value[i] = true;
				} else {
					rlt.value[i] = false;
					carry = true;
				}
			} else if (this.value[this.length - j] || op.value[op.length - j]) {
				if (carry) {
					rlt.value[i] = false;
				} else {
					rlt.value[i] = true;
				}
			} else {
				if (carry) {
					rlt.value[i] = true;
					carry = false;
				} else {
					rlt.value[i] = false;
				}
			}
		}
		if (carry = true) {
			BigInteger rlt2 = new BigInteger(len + 1);
			rlt2.value[0] = true;
			for (int i = 1; i < rlt2.length; i++) {
				rlt2.value[i] = rlt.value[i - 1];
			}
			return rlt2;
		}
		return rlt;
	}

	/*
	 * only for two positive number.
	 */
	public BigInteger minus(BigInteger op) {
		return null;
	}

	public BigInteger multiply(BigInteger op) {
		return null;
	}

	public BigInteger divide(BigInteger op) {
		return null;
	}

	public BigInteger gcd(BigInteger op) {
		return null;
	}

	public BigInteger mod(BigInteger op) {
		return null;
	}

	public BigInteger modPow(BigInteger op) {
		return null;
	}

	public BigInteger modInverse(BigInteger op) {
		return null;
	}

	/*
	 * if this <op ,return -1; else if this =op, return 0; else return 1; only
	 * compare the abs value.
	 */
	public int compareTo(BigInteger op) {
		if (this.length > op.length) {
			return 1;
		} else if (this.length < op.length) {
			return -1;
		} else {
			for (int i = 0; i < this.length; i++) {
				if (this.value[i] && !op.value[i]) {
					return 1;
				} else if (!this.value[i] && op.value[i]) {
					return -1;
				}
			}
		}
		return 0;
	}

	public String toString() {
		StringBuffer buffer = new StringBuffer();
		if (sign == false) {
			buffer.append("-");
		}
		for (int i = 0; i < value.length; i++) {
			if (value[i]) {
				buffer.append("1");
			} else {
				buffer.append("0");
			}
		}
		return buffer.toString();
	}

}
